[ACM] Allow the loadpolicy operation once
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Mon, 23 Jul 2007 08:45:23 +0000 (09:45 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Mon, 23 Jul 2007 08:45:23 +0000 (09:45 +0100)
This patch allows the loadpolicy operation to only happen once, then
require an update until the default policy has been installed (again).

Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
xen/acm/acm_chinesewall_hooks.c
xen/acm/acm_policy.c
xen/acm/acm_simple_type_enforcement_hooks.c
xen/include/acm/acm_hooks.h

index c646c0c03fac0e2fa6160b80657fa9c507262f48..6c1d71c7eb20002013c7ee68ec169bd94531414b 100644 (file)
@@ -650,6 +650,13 @@ static void chwall_domain_destroy(void *object_ssid, struct domain *d)
     return;
 }
 
+
+static int chwall_is_default_policy(void)
+{
+    return ( (chwall_bin_pol.max_types    == 1 ) &&
+             (chwall_bin_pol.max_ssidrefs == 2 ) );
+}
+
 struct acm_operations acm_chinesewall_ops = {
     /* policy management services */
     .init_domain_ssid = chwall_init_domain_ssid,
@@ -674,6 +681,8 @@ struct acm_operations acm_chinesewall_ops = {
     .fail_grant_setup = NULL,
     /* generic domain-requested decision hooks */
     .sharing = NULL,
+
+    .is_default_policy = chwall_is_default_policy,
 };
 
 /*
index 033057b40a8c4a0a4156918577d5887095b5f33d..cf0f61b0d98060918b520380e88fc9610276079d 100644 (file)
@@ -87,9 +87,16 @@ _acm_update_policy(void *buf, u32 buf_size, int is_bootpolicy,
                    struct acm_sized_buffer *errors)
 {
     uint32_t offset, length;
+    static int require_update = 0;
 
     write_lock(&acm_bin_pol_rwlock);
 
+    if (  require_update != 0 &&
+        ( deletions == NULL || ssidchanges == NULL ) )
+    {
+        goto error_lock_free;
+    }
+    require_update = 1;
     /*
        first some tests to check compatibility of new policy with
        current state of system/domains
@@ -153,7 +160,13 @@ _acm_update_policy(void *buf, u32 buf_size, int is_bootpolicy,
            &pol->xml_pol_version,
            sizeof(acm_bin_pol.xml_pol_version));
 
+    if ( acm_primary_ops->is_default_policy() &&
+         acm_secondary_ops->is_default_policy() ) {
+        require_update = 0;
+    }
+
     write_unlock(&acm_bin_pol_rwlock);
+
     return ACM_OK;
 
 error_lock_free:
index 25f83f5566f6c3d03d3065e22f0d517c9102e8be..b9b603516fc5b52be64f193ec8b69bab69d80dd9 100644 (file)
@@ -739,6 +739,14 @@ ste_sharing(ssidref_t ssidref1, ssidref_t ssidref2) {
         return ACM_ACCESS_DENIED;
 }
 
+/* */
+
+static int
+ste_is_default_policy(void)
+{
+    return ( (ste_bin_pol.max_types    == 1) &&
+             (ste_bin_pol.max_ssidrefs == 2) );
+}
 
 /* now define the hook structure similarly to LSM */
 struct acm_operations acm_simple_type_enforcement_ops = {
@@ -768,6 +776,8 @@ struct acm_operations acm_simple_type_enforcement_ops = {
     .pre_grant_setup        = ste_pre_grant_setup,
     .fail_grant_setup       = NULL,
     .sharing                = ste_sharing,
+
+    .is_default_policy      = ste_is_default_policy,
 };
 
 /*
index c2b59dd6ab9d2b2e38e845e693f323a7ff323817..759a1a08432c17bf3adf3ac11af71d4f087f7137 100644 (file)
@@ -113,6 +113,8 @@ struct acm_operations {
     void (*fail_grant_setup)           (domid_t id);
     /* generic domain-requested decision hooks (can be NULL) */
     int (*sharing)                     (ssidref_t ssidref1, ssidref_t ssidref2);
+    /* determine whether the default policy is installed */
+    int (*is_default_policy)           (void);
 };
 
 /* global variables */